package com.代码随想录;

import java.util.HashMap;
import java.util.Map;

/**
 * @author zsj
 * @version 1.0
 * @date 2024/5/12 12:34
 * @description
 */
public class CodeArrayDemo {


//    public static void main(String[] args) {
//        CodeArrayDemo removeArrayItemDemo = new CodeArrayDemo();
//        int[] ints = {1, 3, 3, 4, 5};
//        removeArrayItemDemo.removeItem(ints, 3);
//        System.out.println(Arrays.toString(ints));
//    }

    //删除数组指定值的元素
    public int removeItem(int[] arr, Integer item) {
        if (item == null) throw new NullPointerException();
        int slow = 0;
        int count = 0;
        for (int fast = 0; fast < arr.length; fast++) {
            if (arr[fast] != item) {
                arr[slow++] = arr[fast];
            } else count++;
        }
        int[] in = new int[arr.length - count];
        System.arraycopy(arr, 0, in, 0, arr.length - count);
//        System.out.println(Arrays.toString(in));
        arr = in;
        return slow;
    }

    //给你一个按 非递减顺序 排序的整数数组 nums，返回 每个数字的平方 组成的新数组，要求也按 非递减顺序 排序。
    public int[] sortedSquares(int[] nums) {
        int left = 0;
        int right = nums.length - 1;
        int[] result = new int[nums.length];
        int end = result.length - 1;
        while (left <= right) {
            int left_pom = nums[left] * nums[left];
            int right_pom = nums[right] * nums[right];
            if (left_pom > right_pom) {
                //左边大于右边
                result[end--] = left_pom;
                left++;
            } else {
                //随便放一个咯
                result[end--] = right_pom;
                right--;
            }
        }
        return result;
    }

    //209. 长度最小的子数组
    public int minSubArrayLen(int target, int[] nums) {
        if (nums == null || nums.length == 0) return 0;
        int ans = Integer.MAX_VALUE;//返回的长度
        int sum = 0;//sum求和 大于等于target
        int left = 0;//起步位置 记录是从哪个位置开始的
        for (int i = 0; i < nums.length; i++) {
            sum += nums[i];//去加
            while (sum >= target) {
                //一但出现满足条件的值 我们的起始位置要往后移动
                //每次我们都需要取到这个子序列的长度 并且把它和ans对比看谁短 将ans重新赋值给它
                ans = Math.min(ans, i - left + 1);
                sum -= nums[left++];//每次都把最左边的值排除掉
            }
        }
        return ans == Integer.MAX_VALUE ? 0 : ans;
    }


    //904. 水果成篮
    public static int totalFruit(int[] fruits) {
        //记录每次采摘的最大数量
        int ans = 0, left = 0;
        //哈希表的key是水果类型 1234 value是水果数量
        Map<Integer, Integer> type = new HashMap<>();
        for (int right = 0; right < fruits.length; right++) {
            //往哈希表中添加类型和对应数量 如果没有初始化为1
            type.put(fruits[right],
                    type.getOrDefault(fruits[right], 0) + 1);
            while (type.size() > 2) {
                type.put(fruits[left], type.get(fruits[left]) - 1);//将这个数量-1
                //如果哈希表中的对应类型的数量=0时删除这个类型
                if (type.get(fruits[left]) == 0) type.remove(fruits[left]);
                ++left;
            }
            //每次收集这个长度的序列
            ans = Math.max(ans, right - left + 1);
        }
        return ans;
    }


    public static void main(String[] args) {
        generateMatrix(5);
    }

    //59. 螺旋矩阵 II
    //给你一个正整数 n ，生成一个包含 1 到 n2 所有元素，且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。
    public static int[][] generateMatrix(int n) {
        int[][] result = new int[n][n];//结果数组
        int startX = 0, startY = 0;//起始位置
        int loop = n / 2;//渲染所需循环次数
        int offset = 1;//用来确定终止位置的偏移量
        int count = 1; //每次递增记录的值
        int i = 0, j = 0; //x表示行,j表示列
        //循环时遵循左闭右开原则 也就是包含左边但是不包含最后一个元素
        while (loop-- != 0) {
            //左到右 循环完成后将会到最后一列
            for (j = startY; j < n - offset; j++) {
                result[startX][j] = count++;
            }

            //从上到下 循环完成后将会到最后一行
            for (i = startX; i < n - offset; i++) {
                result[i][j] = count++;
            }

            //从右到左 循环完成后会到第一列
            for (; j > startY; j--) {
                result[i][j] = count++;
            }

            //从下到上 循环完成回到第一行
            for (; i > startX; i--) {
                result[i][j] = count++;
            }
            offset++;
            startX += 1;
            startY += 1;
        }
        if (n % 2 == 1) {
            //说明是奇数
            result[n / 2][n / 2] = count++;
        }
        return result;
    }
}
